#!/usr/bin/perl
require Asm_utils;

################################################################################
                           # Entry point to PASS-1 #
################################################################################

if ($#ARGV != 0)
{
    print_usage();
}

# The files. symbol table file is opened in Asm_utils.pm
open(SIC_ASM_FILE, $ARGV[0]) or die "Cannot find/open $ARGV[0]";
open(INTERIM_ASM_FILE, ">", "pass_1.out") or die "Cannot open pass_1.out";

# The essential variables
my $num_lines = 0;
my $locctr    = 0;
my $start_addr = 0;

GETLINE: while (my $line = <SIC_ASM_FILE>)
{
# More essential variables
   my $label     = "";
   my $opcode    = "";
   my $operand   = "";

   chomp($line);

# Skip comments...
   if ($line =~ /^\./)
   {
      $num_lines++;
      next GETLINE;
   }

   ($label, $opcode, $operand) = tokenize_line($line);

# Special handling for START...
   if ($opcode eq "START")
   {
      $locctr = $start_addr = hex($operand);
      if ($label ne " ")
      {
         update_symtab($label, $locctr);
      }
      print INTERIM_ASM_FILE "$line\n";

      next GETLINE;
   }

# Other opcodes...
   if ($locctr != 0)
   {
      if ($label ne " ")
      {
         update_symtab($label, $locctr);
      }
      if (search_in_optab($opcode) == 1)
      {
         $locctr = $locctr + 3;
      }
      elsif ($opcode eq "WORD") 
      {
         $locctr = $locctr + 3;
      }
      elsif ($opcode eq "RESW") 
      {
         $locctr = $locctr + 3 * $operand;
      }
      elsif ($opcode eq "RESB") 
      {
         $locctr = $locctr + $operand;
      }
      elsif ($opcode eq "BYTE")
      {
# Find length of constant in bytes and add to locctr
         $locctr = $locctr + length_of_operand($operand);
      }
      elsif ($opcode eq "END")
      {
         last GETLINE;
      }
      else 
      {
         die "Invalid opcode $opcode\n";
      }

      print INTERIM_ASM_FILE "$line\n";
   }
}

# Basic Error handling
if ($locctr == 0)
{
   print "ASM file does not contain START directive\n";
}

write_symtab_to_file();

my $prog_len = $locctr - $start_addr;
print INTERIM_ASM_FILE "$line\n";
print "-------------------- Pass 1 --------------------\n";
print "Program length : $prog_len\n";
print "Interim file: pass_1.out\n";
print "Symbol table: symtab.out\n";
print "-------------------- End of Pass 1 --------------------\n";

################################################################################
                               # End of PASS-1 #
################################################################################
